<template>
  <div class="toolbar">
    <el-button size="small" @click="revock">撤销</el-button>
    <el-button size="small" @click="recover">恢复</el-button>
    <label for="insert" class="insert">
      插入图片
      <input
        type="file"
        id="insert"
        hidden
        @change="insertImg"
        ref="insertImgRef"
      />
    </label>
    <el-button
      size="small"
      :disabled="curComponent == null || curComponentList.length <= 1"
      @click="compose"
      >组合</el-button
    >
    <el-button
      size="small"
      :disabled="
        curComponent == null ||
        curComponent.component != 'Group' ||
        curComponentList.length > 1
      "
      @click="split"
      >拆分</el-button
    >
    <el-button size="small" :disabled="islock" @click="setLock(!islock)"
      >锁定</el-button
    >
    <el-button
      size="small"
      :disabled="this.curComponent == null || !islock"
      @click="setLock(!islock)"
      >解锁</el-button
    >
    <el-button size="small" @click="screenShot">截图</el-button>

    <div class="canvas-config">
      <span>画布大小</span>
      <input
        type="number"
        class="size"
        v-model="canvasStyle.width"
        @change="changeCanvasSize"
      />
      <span>*</span>
      <input
        type="number"
        class="size"
        v-model="canvasStyle.height"
        @change="changeCanvasSize"
      />
    </div>

    <div class="right">
      <el-button size="small" @click="clear">清空画布</el-button>
      <el-button size="small" @click="save">保存</el-button>
      <el-button size="small" @click="showPreview">预览</el-button>

      <!-- 发布弹窗 -->
      <el-popover
        placement="bottom"
        width="420"
        trigger="click"
        popper-class="popover_publish loading"
        v-model="publishPopoverVisible"
        @show="handleShow"
        @hide="handleHide"
      >
        <el-form>
          <el-form-item class="close">
            <span @click="publishPopoverVisible = false" class="close_span">
              <i class="el-icon-close"></i>
            </span>
          </el-form-item>
          <el-form-item>
            <h3>发布当前页面</h3>
          </el-form-item>
          <el-form-item>
            <span>发布方式<i class="el-icon-info"></i></span>
            <el-radio v-model="radio" label="1">Web端</el-radio>
          </el-form-item>
          <el-form-item>
            <div class="submit">
              <el-button type="text" @click="showManageDialog"
                >管理已发布页面</el-button
              >
              <span style="line-height: 40px">
                <el-button type="primary" @click="onSubmit" size="mini"
                  >确认</el-button
                >
                <el-button size="mini" @click="publishPopoverVisible = false"
                  >取消</el-button
                >
              </span>
            </div>
          </el-form-item>
        </el-form>
        <el-button
          size="small"
          type="primary"
          slot="reference"
          class="publish"
          ref="publishBtnRef"
          >发布</el-button
        >
      </el-popover>

      <!-- 发布成功弹窗 -->
      <el-popover
        placement="bottom"
        width="420"
        trigger="click"
        popper-class="popover_publish"
        v-model="successPopoverVisibel"
        @show="handleShow"
        @hide="hideSuccessPopover"
      >
        <el-form>
          <el-form-item class="close">
            <span @click="cancelPush" class="close_span">
              <i class="el-icon-close"></i>
            </span>
          </el-form-item>
          <el-form-item>
            <h3>是否立即跳转到发布页面</h3>
          </el-form-item>
          <el-form-item>
            <el-row>
              <el-col :span="6">发布页网址：</el-col>
              <el-col :span="18" ref="pathRef"></el-col>
            </el-row>
          </el-form-item>
          <el-form-item>
            <el-row>
              <el-col :span="6">发布时间：</el-col>
              <el-col :span="18" ref="dateRef"></el-col>
            </el-row>
          </el-form-item>
          <el-form-item>
            <div class="submit">
              <el-button type="text" @click="showManageDialog"
                >管理已发布页面</el-button
              >
              <span style="line-height: 40px">
                <el-button type="primary" @click="pushToPage" size="mini"
                  >跳转</el-button
                >
                <el-button size="mini" @click="cancelPush">取消</el-button>
              </span>
            </div>
          </el-form-item>
        </el-form>
        <el-button
          size="small"
          type="primary"
          slot="reference"
          class="publish"
          ref="successBtnRef"
          style="display: none"
          ><i class="el-icon-circle-check"></i>发布成功</el-button
        >
      </el-popover>
    </div>
    <!-- 管理发布页的弹窗 -->
    <el-dialog
      title="管理发布页"
      :visible.sync="manageDialogVisible"
      top="200px"
      @open="handleShow"
      @closed="handleHide"
    >
      <el-table :data="pageDataList" border>
        <el-table-column
          property="id"
          label="序号"
          width="50px"
        ></el-table-column>
        <el-table-column property="date" label="发布时间" width="170px">
          <template v-slot="scoped">
            {{ scoped.row.date | formatDate }}
          </template>
        </el-table-column>
        <el-table-column property="path" label="链接" width="300px">
          <template v-slot="scoped">
            <el-link
              :ref="`publicLinkRef${scoped.row.id}`"
              :href="`http://localhost:50000${scoped.row.path}`"
              type="primary"
              >http://localhost:50000{{ scoped.row.path }}</el-link
            >
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="scoped">
            <el-tooltip
              class="item"
              effect="dark"
              content="复制网址"
              placement="top"
              :enterable="false"
            >
              <el-button
                type="primary"
                icon="el-icon-scissors"
                size="mini"
                @click="copyPath(scoped.row.path)"
              ></el-button>
            </el-tooltip>
            <el-button
              type="danger"
              icon="el-icon-delete"
              size="mini"
              @click="removeAddressById(scoped.row.id)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
  </div>
</template>

<script>
import { mapMutations, mapState } from "vuex";
import bus from "@/utils/eventBus.js";
import { list } from "@/components/component-list.js";
import axios from "axios";
import { Loading } from "element-ui";
import {
  listenGlobalKeydown,
  removeGlobalKeydown,
} from "@/utils/shortcutKey.js";

export default {
  data() {
    return {
      timer: null,
      radio: "1",
      publishPopoverVisible: false,
      successPopoverVisibel: false,
      // 当前发布页的Id
      publishId: 0,
      // 控制管理发布页的显示与隐藏
      manageDialogVisible: false,
      // 发布页数据
      pageDataList: [],
      // 最新的发布页
      lastPageData: null,
    };
  },
  created() {
    this.getPublishPageData();
  },
  computed: {
    ...mapState([
      "curComponent",
      "canvasStyleData",
      "publishRoutes",
      "componentData",
      "curComponentList",
    ]),
    islock() {
      if (this.curComponent == null) return true;
      return this.curComponent.islock;
    },
    canvasStyle() {
      return { ...this.canvasStyleData };
    },
  },
  methods: {
    ...mapMutations([
      "backP",
      "forwardP",
      "saveHistoryState",
      "resetData",
      "setPreview",
      "saveData",
      "setLock",
      "compose",
      "split",
      "modifiedPublishData",
      "setScreenShot",
    ]),
    revock() {
      this.backP();
    },
    recover() {
      this.forwardP();
    },
    clear() {
      this.$confirm("确认清空画布？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          // 确认清空
          this.saveHistoryState();
          this.resetData([]);
        })
        .catch(() => {
          return;
        });
    },
    save() {
      this.saveData();
    },
    insertImg(e) {
      const file = e.target.files[0];
      if (!file.type.includes("image")) {
        return this.$message.error("只能上传图片！");
      }
      const reader = new FileReader();
      reader.onload = (res) => {
        const fileResult = res.target.result;

        const img = new Image();
        img.src = fileResult;
        img.onload = () => {
          // 获取图片控件的基本信息
          const imgMsg = list.find((item) => item.component == "VImg");

          // 等比例缩放图片
          const newWidth = Math.ceil(
            imgMsg.style.height * (img.width / img.height)
          );
          img.width = newWidth;
          img.height = imgMsg.style.height;

          // 通过 eventBus 将数据传给Editor
          bus.$emit("createImg", img);

          // 修复重复上传同一文件，@change 不触发的问题
          this.$refs.insertImgRef.setAttribute("type", "text");
          this.$refs.insertImgRef.setAttribute("type", "file");
        };
      };
      reader.readAsDataURL(file);
    },
    changeCanvasSize() {
      this.canvasStyle.width = (this.canvasStyle.width + "").trim();
      this.canvasStyle.height = (this.canvasStyle.height + "").trim();

      if (
        this.canvasStyle.width == "" ||
        this.canvasStyle.height == "" ||
        this.canvasStyle.width < 0 ||
        this.canvasStyle.height < 0
      ) {
        this.canvasStyle.width = this.canvasStyleData.width;
        this.canvasStyle.height = this.canvasStyleData.height;
        this.$message.error("画布大小不能为空或负数！");
      }

      this.$store.commit("setCanvasStyle", this.canvasStyle);
    },
    // 点击发布时的处理事件
    onSubmit() {
      const options = {
        target: ".loading",
        fullscreen: false,
        text: "Web端发布中...",
        spinner: "el-icon-loading",
      };
      let loadingInstance = Loading.service(options);
      setTimeout(async () => {
        // 保存路由到数据库的路由表
        const publishRoute = {
          id: this.publishId,
          path: `/publish/${this.publishId}`,
        };

        // 将新增的路由表和路由路径发送到服务器
        const { data: res_router } = await axios.post(
          "/routerlist",
          publishRoute
        );
        if (res_router.status !== 0) {
          loadingInstance.close();
          return this.$message.error(res_router.message);
        }

        // 如果保存路由成功 则保存路由的组件信息
        const pageData = {
          id: this.publishId,
          componentData: JSON.stringify(this.componentData),
        };

        const { data: res_page } = await axios.post("/publishPage", pageData);
        if (res_page.status !== 0) {
          loadingInstance.close();
          return this.$message.error(res_page.message);
        }
        loadingInstance.close();
        this.$message.success(res_page.message);

        // 点击发布时同时更新 id 和 pageDataList
        this.getPublishPageData();

        // 切换按钮显示
        this.$refs.publishBtnRef.$el.style.display = "none";
        this.$refs.successBtnRef.$el.style.display = "inline-block";
        // 切换显示框
        this.publishPopoverVisible = false;
        this.successPopoverVisibel = true;
      }, 5000);
    },
    // 初始化发布页面的Id并获取发布页数据列表
    async getPublishPageData() {
      const { data: res } = await axios.get("/routerList");
      this.publishId = res.data.length + 1;
      this.pageDataList = res.data;

      if (this.pageDataList.length > 0) {
        // 如果发布页数据不为空，则保存最新发布页
        this.lastPageData = this.pageDataList[this.publishId - 2];

        // 添加最新发布成功的文字
        this.$refs.pathRef.$el.innerText = `http://localhost:50000${this.lastPageData.path}`;
        this.$refs.dateRef.$el.innerText = this.$options.filters["formatDate"](
          this.lastPageData.date
        );
      }
    },
    // 展示管理发布页
    showManageDialog() {
      this.manageDialogVisible = true;
      this.publishPopoverVisible = false;
    },
    // 删除发布页
    async removeAddressById(id) {
      const confirmResult = await this.$confirm(
        "此操作将永久删除该发布页, 是否继续?",
        "提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }
      ).catch((err) => err);

      // 当点击确认删除时，返回字符串confirm
      // 当点击取消删除时，返回字符串cancel
      if (confirmResult !== "confirm") return this.$message.info("已取消删除");

      const { data: res_page } = await axios.delete(`/publishPage/${id}`);
      if (res_page.status !== 0) {
        return this.$message.error(res_page.message);
      }
      const { data: res_router } = await axios.delete(`/routerList/${id}`);
      if (res_router.status !== 0) {
        return this.$message.error(res_router.message);
      }
      this.$message.success(res_router.message);

      // 删除发布页时同时更新 id 和 pageDataList
      this.getPublishPageData();
    },
    // 点击复制操作
    copyPath(val) {
      val = `http://localhost:50000${val}`;
      let url = val; // 后台接口返回的链接地址
      let inputNode = document.createElement("input"); // 创建input
      inputNode.value = url; // 赋值给 input 值
      document.body.appendChild(inputNode); // 插入进去
      inputNode.select(); // 选择对象
      document.execCommand("Copy"); // 原生调用执行浏览器复制命令
      // inputNode.className = 'oInput'
      inputNode.style.display = "none"; // 隐藏
      this.$message({
        type: "success",
        message: "已复制网址到粘贴板",
        center: true,
        iconClass: "el-icon-s-order",
        customClass: "copy",
      });
    },
    // 跳转到发布页
    pushToPage() {
      const path = this.lastPageData.path;
      this.$router.push(path);
    },
    // 取消跳转的处理事件
    cancelPush() {
      this.copyPath(this.lastPageData.path);
      this.successPopoverVisibel = false;
    },
    // 关闭发布成功弹出框时触发
    hideSuccessPopover() {
      listenGlobalKeydown();
      // 切换按钮显示
      this.$refs.publishBtnRef.$el.style.display = "inline-block";
      this.$refs.successBtnRef.$el.style.display = "none";
    },
    screenShot() {
      this.setPreview(true);
      this.setScreenShot(true);
    },
    showPreview() {
      this.setPreview(true);
      this.setScreenShot(false);
    },
    // 处理展示弹出框的事件
    handleShow() {
      // 取消全局快捷键
      removeGlobalKeydown();
    },
    handleHide() {
      listenGlobalKeydown();
    },
  },
  filters: {
    formatDate(date) {
      const dateTime = new Date(date);

      const y = dateTime.getFullYear();
      const m = (dateTime.getMonth() + 1 + "").padStart(2, "0");
      const d = (dateTime.getDate() + "").padStart(2, "0");

      const hh = (dateTime.getHours() + "").padStart(2, "0");
      const mm = (dateTime.getMinutes() + "").padStart(2, "0");
      const ss = (dateTime.getSeconds() + "").padStart(2, "0");

      return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
    },
  },
};
</script>

<style lang="less" scoped>
.toolbar {
  background-color: #fff;
  border-bottom: 1px solid #ddd;
  padding: 15px 10px;
}

.canvas-config {
  display: inline-block;
  margin-left: 15px;
  font-size: 14px;
  input {
    width: 50px;
    height: 15px;
    border: 1px solid #ddd;
  }
  span {
    margin: 0 5px;
  }
}

.insert {
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  background: #fff;
  border: 1px solid #dcdfe6;
  color: #606266;
  text-align: center;
  box-sizing: border-box;
  outline: 0;
  margin: 0;
  transition: 0.1s;
  font-weight: 500;
  padding: 9px 15px;
  font-size: 12px;
  border-radius: 3px;
  margin: 0 10px;

  &:active {
    color: #3a8ee6;
    border-color: #3a8ee6;
    outline: 0;
  }

  &:hover {
    background-color: #ecf5ff;
    color: #3a8ee6;
  }
}

// 去除输入框的滚动条
.size::-webkit-outer-spin-button,
.size::-webkit-inner-spin-button {
  -webkit-appearance: none;
}
.size[type="number"] {
  -moz-appearance: textfield;
}

.right {
  float: right;
}

.publish {
  margin-left: 10px;
}

.el-radio {
  margin-left: 20px;
}

.el-form-item {
  h3 {
    font-size: 18px;
  }
}

/deep/ .el-form-item__content {
  line-height: 1px;
}

.submit {
  width: 100%;
  display: flex;
  justify-content: space-between;
}

.close {
  display: flex;
  justify-content: flex-end;
  font-weight: 700;
  margin-bottom: 0;
}

/deep/ .el-dialog__header {
  display: block;
}
</style>

<style lang="less">
.popover_publish {
  padding: 10px 20px !important;
}
.copy {
  background-color: rgba(255, 255, 255, 0.9) !important;
  min-width: 0 !important;
  border-radius: 10px !important;
  box-shadow: 0 3px 8px rgba(10, 16, 20, 0.24), 0 0 8px rgba(10, 16, 20, 0.12) !important;
}

.el-icon-circle-check,
.el-icon-s-order {
  margin-right: 3px !important;
}

.el-icon-close:hover {
  background-color: #eee !important;
}
</style>
